#include "../include/Engine.hpp"
using namespace klas;

bool Engine::m_initExternal = false;

void initWindow(const Vector2<Real>& dim, Real BPP, Real near, Real far)
{ 
  // -------------------------------------
  // init SDL first
  int error;
	error = SDL_Init(SDL_INIT_EVERYTHING);

	Uint32 flags = SDL_OPENGL;
	SDL_SetVideoMode(dim.x, dim.y, BPP, flags);

	
	  
	// -------------------------------------
	// now init OpenGL
/*	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);*/

	 //Set clear color
	glClearColor( 0, 0, 0, 1 );
	glMatrixMode( GL_PROJECTION );
	glPushMatrix();
	glLoadIdentity();
	glOrtho( 0, dim.x, dim.y, 0.0f, near, far);
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();
	glLoadIdentity();
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glFrontFace(GL_CW);
	//glEnable(GL_ALPHA_TEST);
	//glEnable(GL_TEXTURE_ENV);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_CULL_FACE);
	//glEnable(GL_DEPTH_TEST);
	//glDepthMask(GL_TRUE);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);      // 4-byte pixel alignment
	glShadeModel(GL_SMOOTH);                    // shading mathod: GL_SMOOTH or GL_FLAT
}


Engine::Engine(const Vector2<Real>& windowDim)
{
	if(m_initExternal == false)
	{
		ilInit();
		iluInit();
		m_initExternal = true;
	}
	
	initWindow(windowDim, 32, 5, -5);
	
	m_cam = new Camera(windowDim);
	m_scene = NULL;
	m_particle = NULL;
	m_postProcessor = NULL;
	m_postProcessParticles = false;
}

Engine::~Engine()
{
	if(m_cam)
	{
		delete(m_cam);
		m_cam = NULL;
	}
	
	// Exit SDL and related libraries
	Mix_CloseAudio();
	SDL_Quit();
	
	// We don't delete the scene, the particle engine, or the post-processor.
	m_scene = NULL;
	m_particle = NULL;
	m_postProcessor = NULL;
}

void Engine::setScene(Scene* scene)
{
	m_scene = scene;	
}

void Engine::setParticleEngine(ParticleEngine* engine)
{
	m_particle = engine;
}

void Engine::setPostProcessor(PostProcessor* postProcessor, bool particles)
{
	m_postProcessParticles = particles;
	m_postProcessor = postProcessor;
}

void Engine::setCaption(string window, string icon)
{
	if(icon != "USE_WINDOW__")
		SDL_WM_SetCaption(window.c_str(), icon.c_str());
	else
		SDL_WM_SetCaption(window.c_str(), window.c_str());
}

Camera* Engine::getCamPtr()
{
	return m_cam;
}

bool Engine::render()
{
	// Return false if either of our ptrs is null.
	if(!m_cam)
		return false;
	
	if(m_postProcessor)
		m_postProcessor->renderingStarted();
	
	if(m_scene)
		m_scene->render(m_cam->getRect());
	
	if(m_particle && m_postProcessParticles)
    m_particle->render(*m_cam);
    
  if(m_postProcessor)
  {
  	m_postProcessor->renderingFinished();
  	m_postProcessor->render();
  }
  	
  if(m_particle && !m_postProcessParticles)
  	m_particle->render(*m_cam);
	
	/* render UI here */
	
	if(m_scene)
		m_scene->renderFonts();
		
	SDL_GL_SwapBuffers();
	glClear(GL_COLOR_BUFFER_BIT);
	return true;
}
